﻿namespace Lexer

module Tocken =
    type Type =
        | ID
        | NUM
        // keywords
        | INT
        | IF
        | ELSE
        | RETURN
        // operators
        | ADD // +
        | AS // =
        | RELOP // relational operator
        // delimits
        | SEM // ;
        | LP // (
        | RP // )
        | LBS // {
        | RBS // }
        | COM
        | ERROR
        | END

    type Tocken(value: string, ty: string) =
        let _typeName =
            match ty with
            | "ID" -> ID
            | "NUM" -> NUM
            // keywords
            | "INT" -> INT
            | "IF" -> IF
            | "ELSE" -> ELSE
            | "RETURN" -> RETURN
            // operators
            | "ADD" -> ADD // +
            | "AS" -> AS // =
            // delimits
            | "SEM" -> SEM // ;
            | "LP" -> LP // (
            | "RP" -> RP // )
            | "LBS" -> LBS // {
            | "RBS" -> RBS // }
            | "EQ" -> RELOP
            | "LE" -> RELOP // <=
            | "GE" -> RELOP // >=
            | "NE" -> RELOP // !=
            | "LT" -> RELOP // <
            | "GT" -> RELOP // >
            | _ -> ERROR


        member this.Value = value
        member this.TypeName = _typeName

    let createTocken (str: string): Tocken =
        let index = Seq.findIndex ((=) ',') str

        let typeName =
            str
            |> Seq.take index
            |> Seq.filter System.Char.IsLetterOrDigit
            |> System.String.Concat

        let value =
            str
            |> Seq.skip (index + 1)
            |> Seq.filter (fun x -> ((x <> '>') && (x <> ' ')))
            |> System.String.Concat


        Tocken(value, typeName)
